package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"net/url"
	"os"
	"strings"
	"time"
)

func getEnv(key, fallback string) string {
	if value, ok := os.LookupEnv(key); ok {
		return value
	}
	return fallback
}

func getListenAddress() string {
	port := getEnv("PORT", "80")
	return ":" + port
}

func serveReverseProxy(target string, res http.ResponseWriter, req *http.Request) {
	// parse the url
	url, _ := url.Parse(target)

	// create the reverse proxy
	proxy := httputil.NewSingleHostReverseProxy(url)

	// Update the headers to allow for SSL redirection
	req.URL.Host = url.Host
	req.URL.Scheme = url.Scheme
	req.Header.Set("X-Forwarded-Host", req.Header.Get("Host"))
	req.Host = url.Host

	// Note that ServeHttp is non blocking and uses a go routine under the hood
	proxy.ServeHTTP(res, req)
}

func getDomains() []string {
	filepath := "./domain.conf"
	content, err := ioutil.ReadFile(filepath)
	if err != nil {
		panic(err)
	}
	return strings.Split(string(content), ",")
}
func handleRequestAndRedirect(res http.ResponseWriter, req *http.Request) {
	domains := getDomains()
	t := time.Now()
	hour := t.Hour()
	minute := t.Minute()
	rdomain := domains[1:]

	// t1 := time.Now().Unix()
	// t1 = t1 % 300
	if req.Host == domains[0] {
		subdomain := fmt.Sprintf("%d-%d", minute/5, hour)
		subdomain, err := EnPwdCode([]byte(subdomain))
		if err != nil {
			return
		}
		targetDomain := rdomain[hour%len(rdomain)]
		realDomain := fmt.Sprintf("http://%s.%s", subdomain, targetDomain)
		http.Redirect(res, req, realDomain, http.StatusMovedPermanently)
	} else {
		var url string = "http://m.baidu.com"
		if parseDomain(req.Host) == true {
			url = "http://app.qwpool.cn"
		}
		serveReverseProxy(url, res, req)
	}
}
func parseDomain(url string) bool {
	domains := getDomains()
	t := time.Now()
	hour := t.Hour()
	minute := t.Minute()
	rdomain := domains[1:]
	sub := strings.Split(url, ".")
	if len(sub) != 3 {
		return false
	}
	subdomain := sub[0]
	subdomain, err := DePwdCode(subdomain)
	if err != nil {
		return false
	}
	targetDomain := strings.Join(sub[1:], ".")
	if fmt.Sprintf("%d-%d", minute/5, hour) != subdomain {
		return false
	}
	if rdomain[hour%len(rdomain)] != targetDomain {
		return false
	}
	return true
}
func main() {
	http.HandleFunc("/", handleRequestAndRedirect)
	if err := http.ListenAndServe(getListenAddress(), nil); err != nil {
		panic(err)
	}
}
